package com.lepu.app.fun.chat.business.uiflow;


import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;

import com.app.application.MyApplication;
import com.core.lib.utils.main.LogUtilBase;
import com.eyzhs.app.R;
import com.lepu.app.fun.chat.activity.CommonActivity;
import com.lepu.app.fun.chat.controller.base.AbsBaseFragment;
import com.lepu.app.fun.chat.util.ReturnResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import common.db.Constants;
import util.ResourceUtil;
import util.XmlManager;


public class UIFlowManager {

    static class UIFlowManagerHelper {
        private static UIFlowManager instance = new UIFlowManager();
    }

    public static UIFlowManager getInstance() {
        return UIFlowManagerHelper.instance;
    }

    private Map<String, UIComDesc> uiflowMap = new HashMap<String, UIComDesc>();

    //    private Logger logger = LoggerFactory.getLogger(UIFlowManager.class);
    private static final String TAG = UIFlowManager.class.getSimpleName();


    private UIFlowManager() {

        MyApplication appContext = MyApplication.getInstance();
        InputStream is = appContext.getResources().openRawResource(R.raw.uiflow_conf);
        String content = ResourceUtil.getStreamAsString(is, "utf-8");
        initUIFlow(content);
    }

    private void initUIFlow(String content) {
        Document dom = XmlManager.createDomByString(content);
        String defPackage = dom.getDocumentElement().getAttribute("package");
        NodeList nl = dom.getDocumentElement().getChildNodes();
        for (int i = 0; i < nl.getLength(); i++) {
            if (nl.item(i).getNodeType() != Node.ELEMENT_NODE)
                continue;
            Element ele = (Element) nl.item(i);
            UIComDesc uicom = new UIComDesc();
            uicom.init(ele, defPackage);

            NodeList gonl = ele.getChildNodes();
            //子节点中的二级节点
            for (int j = 0; j < gonl.getLength(); j++) {
                if (gonl.item(j).getNodeType() != Node.ELEMENT_NODE)
                    continue;
                Element goele = (Element) gonl.item(j);
                GoAction goAction = new GoAction();
                goAction.init(goele, defPackage);
                uicom.addGoAction(goAction.getName(), goAction);
            }
            uiflowMap.put(uicom.getName(), uicom);
        }

    }

    public UIComDesc getTargetUI(AbsBaseFragment srcFragment, String goActionName) {
        String srcName = ((Object) srcFragment).getClass().getName();
        UIComDesc uicom = uiflowMap.get(srcName);
        if (uicom == null) {
            LogUtilBase.LogE(TAG, "getTargetUI src fragment :" + srcName + " relation uicomdes is null");
            throw new RuntimeException("getTargetUI src fragment :" + srcName + " relation uicomdes is null");
        }

        GoAction goAction = uicom.getGoAction(goActionName);

        UIComDesc targetUICom = uiflowMap.get(goAction.getTarget());

        return targetUICom;
    }

    public GoAction getGoAction(AbsBaseFragment srcFragment, String goActionName) {
        String srcName = ((Object) srcFragment).getClass().getName();
        UIComDesc uicom = uiflowMap.get(srcName);
        if (uicom == null) {
            LogUtilBase.LogE(TAG, "getGoAction src fragment :" + srcName + " relation uicomdes is null");
            throw new RuntimeException("getGoAction src fragment :" + srcName + " relation uicomdes is null");
        }
        GoAction goAction = uicom.getGoAction(goActionName);
        return goAction;
    }


    public void performGoFragmentAction(FragmentActivity activity, AbsBaseFragment srcFragment, String goActionName, Bundle param, int requestCode) {
        try {
            GoAction goAction = getGoAction(srcFragment, goActionName);
            String containerActivity = goAction.getContainerActivity();
            if (containerActivity != null && containerActivity.equals("common")) {
                Intent i = new Intent(activity, CommonActivity.class);
                Bundle bundle = new Bundle();
                bundle.putString(Constants.PARAM_TARGET_FRAGMENT, goAction.getTarget());
                if (param != null) {
                    bundle.putBundle(Constants.PARAM_BUNDLE_PARAM, param);
                }
                i.putExtras(bundle);
                srcFragment.startActivityForResult(i, requestCode);
                UITransition.setActivityStartRightIn(activity);
            } else {
                UIComDesc targetUICom = uiflowMap.get(goAction.getTarget());
                AbsBaseFragment targetFragment = (AbsBaseFragment) Class.forName(targetUICom.getName()).newInstance();
                int containerId = srcFragment.getId();
                if (param != null) {
                    targetFragment.setArguments(param);
                }
                FragmentManager manager = activity.getSupportFragmentManager();
                FragmentTransaction transaction = manager.beginTransaction();
                UITransition.setFragTransRightInRightOut(transaction);
                transaction.replace(containerId, targetFragment);
                transaction.addToBackStack(null);
                transaction.commit();
            }
        } catch (Throwable ex) {
            LogUtilBase.LogE(TAG, ex.toString());
        }
    }

    public void performGoActivityAction(FragmentActivity activity, AbsBaseFragment srcFragment, String goActionName, Bundle param, int requestCode, ReturnResult reqResult) {

        try {
            UIComDesc targetUICom = this.getTargetUI(srcFragment, goActionName);

            Class cls = (Class) Class.forName(targetUICom.getName());
            Intent i = new Intent(activity, cls);
            String intentflag = targetUICom.getAttribute("intent-flag");
            if (intentflag != null) {
                if (intentflag.equals("FLAG_ACTIVITY_SINGLE_TOP")) {
                    i.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
                }
            }

            if (param != null) {
                i.putExtras(param);
            }
            srcFragment.startActivityForResult(i, requestCode);
            UITransition.setActivityStartRightIn(activity);
        } catch (Exception ex) {
            LogUtilBase.LogE(TAG, ex.toString());
        }
    }

    public void performGoActivityAction(FragmentActivity activity, String goActionName, UIComDesc targetUICom, Bundle param) {
        try {

            Class targetActivity = (Class) Class.forName(targetUICom.getName());

            Intent i = new Intent(activity, targetActivity);
            String intentflag = targetUICom.getAttribute("intent-flag");
            if (intentflag != null) {
                if (intentflag.equals("FLAG_ACTIVITY_SINGLE_TOP")) {
                    i.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
                }
            }
            if (param != null) {
                i.putExtras(param);
            }
            activity.startActivity(i);
            UITransition.setActivityStartRightIn(activity);
        } catch (Exception ex) {
            LogUtilBase.LogE(TAG, ex.toString());
        }
    }

    public void performGoActivityAction(FragmentActivity activity, String goActionName, Bundle param) {
        try {
            String srcName = ((Object) activity).getClass().getName();
            UIComDesc uicom = uiflowMap.get(srcName);
            if (uicom == null)
                throw new RuntimeException("src fragment :" + srcName + " relation uicomdes is null");

            GoAction goAction = uicom.getGoAction(goActionName);
            String containerActivity = goAction.getContainerActivity();
            if ("common".equals(containerActivity)) {
                Intent i = new Intent(activity, CommonActivity.class);
                Bundle bundle = new Bundle();
                bundle.putString(Constants.PARAM_TARGET_FRAGMENT, goAction.getTarget());
                if (param != null) {
                    bundle.putBundle(Constants.PARAM_BUNDLE_PARAM, param);
                }
                i.putExtras(bundle);
                activity.startActivity(i);
                UITransition.setActivityStartRightIn(activity);
            } else {
                UIComDesc targetUICom = uiflowMap.get(goAction.getTarget());
                this.performGoActivityAction(activity, goActionName, targetUICom, param);
            }
        } catch (Exception ex) {
            LogUtilBase.LogE(TAG, ex.toString());
        }
    }

    public void popBackStack(FragmentActivity activity, AbsBaseFragment fromFragment, Bundle param) {
        FragmentManager manager = activity.getSupportFragmentManager();

        int statckCount = manager.getBackStackEntryCount();
        if (statckCount == 0 && "CommonActivity".equals(activity.getClass().getSimpleName())) {
            activity.finish();
            UITransition.setActivityFinishRightOut(activity);
            return;
        }
        if (param != null) {
            List<Fragment> fragList = manager.getFragments();
            List<Fragment> existsFragList = new ArrayList();
            for (Fragment frag : fragList) {
                if (frag != null) {
                    existsFragList.add(frag);
                }
            }
            int preFragmentIndex = existsFragList.size() >= 2 ? existsFragList.size() - 2 : 0;
            AbsBaseFragment fragment = (AbsBaseFragment) existsFragList.get(preFragmentIndex);
            fragment.setBackArguments(param, ((Object) fromFragment).getClass().getName());
        }
        manager.popBackStack();
    }

    public void popBackStack(FragmentActivity activity, AbsBaseFragment fromFragment) {
        //// TODO: 2015/11/28  243 is null
        if (activity != null && activity.getSupportFragmentManager() != null) {
            FragmentManager manager = activity.getSupportFragmentManager();
            int statckCount = manager.getBackStackEntryCount();
            if (statckCount == 0 && "CommonActivity".equals(activity.getClass().getSimpleName())) {
                activity.finish();
                UITransition.setActivityFinishRightOut(activity);
                return;
            }

            int fargId = manager.getBackStackEntryAt(statckCount - 1).getId();
            AbsBaseFragment fragment = (AbsBaseFragment) manager.getFragments().get(statckCount - 1);
            fragment.resetBackReturnCode();
            manager.popBackStack();
        }
    }

    public void popToRoot(FragmentActivity activity, AbsBaseFragment absBaseFragment) {
        FragmentManager manager = activity.getSupportFragmentManager();

        int statckCount = manager.getBackStackEntryCount();
        if (statckCount == 0 && "CommonActivity".equals(activity.getClass().getSimpleName())) {
            activity.finish();
            UITransition.setActivityFinishRightOut(activity);
            return;
        }
        AbsBaseFragment fragment = (AbsBaseFragment) manager.getFragments().get(0);
        fragment.resetBackReturnCode();

        //fragment.getId()
        manager.popBackStack();
    }

    public void popToMainRoot(FragmentActivity activity, AbsBaseFragment absBaseFragment) {
        if ("CommonActivity".equals(activity.getClass().getSimpleName())) {
            activity.finish();
            UITransition.setActivityFinishRightOut(activity);
        }
    }

}
